package cn.school.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.school.common.utils.SysUserUtils;
import cn.school.sys.entity.SysDept;
import cn.school.sys.entity.SysRole;
import cn.school.sys.entity.SysUser;
import cn.school.sys.service.SysDeptService;
import cn.school.sys.service.SysRoleService;
import cn.school.sys.service.SysUserService;
import cn.school.sys.vo.SysUserTeacherImportVo;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.ArrayList;
import java.util.List;

/**
 * @className: TeacherImportListener
 * @author: fangjin.tao
 * @date: 2022/12/15
 **/
public class TeacherImportListener extends AnalysisEventListener<SysUserTeacherImportVo> {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(TeacherImportListener.class);
	/**
	 * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
	 */
	private static final int BATCH_COUNT = 50;
	private int ALL_COUNT = 0;
	List<SysUserTeacherImportVo> list = new ArrayList<SysUserTeacherImportVo>();
	/**
	 * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
	 *
	 * @param sysUserService
	 */
	private SysUserService sysUserService;
	private PasswordEncoder passwordEncoder;
	private SysDeptService sysDeptService;
	private SysRoleService sysRoleService;
	
	public TeacherImportListener(SysUserService sysUserService, PasswordEncoder passwordEncoder, SysDeptService sysDeptService,SysRoleService sysRoleService) {
		this.sysUserService = sysUserService;
		this.passwordEncoder = passwordEncoder;
		this.sysDeptService = sysDeptService;
		this.sysRoleService = sysRoleService;
	}
	
	@Override
	public void invoke(SysUserTeacherImportVo sysUserTeacherImportVo, AnalysisContext analysisContext) {
		LOGGER.info("解析到一条数据:{}", JSON.toJSONString(sysUserTeacherImportVo));
		list.add(sysUserTeacherImportVo);
		ALL_COUNT++;
		// 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存
		if (list.size() >= BATCH_COUNT) {
			saveBizData();
			// 存储完成清理 list
			list.clear();
			ALL_COUNT = 0;
		}
	}
	
	@Override
	public void doAfterAllAnalysed(AnalysisContext analysisContext) {
		// 这里也要保存数据，确保最后遗留的数据也存储到数据库
		this.saveBizData();
		LOGGER.info("所有数据解析完成！");
	}
	
	/**
	 * 加上存储数据库
	 */
	private void saveBizData() {
		this.LOGGER.info("{}条数据，开始存储数据库！", ALL_COUNT);
		for (SysUserTeacherImportVo sysUserTeacherImportVo : list) {
			try {
				if (StrUtil.isEmpty(sysUserTeacherImportVo.getUsername())) {
					continue;
				}
				if (StrUtil.isEmpty(sysUserTeacherImportVo.getDeptName())) {
					continue;
				}
				if (StrUtil.isEmpty(sysUserTeacherImportVo.getPhone())) {
					continue;
				}
				if (StrUtil.isEmpty(sysUserTeacherImportVo.getEmail())) {
					continue;
				}
				String password = sysUserTeacherImportVo.getPassword();
				SysUser dbUserNameInfo = sysUserService.getByUserName(sysUserTeacherImportVo.getUsername(), true);
				
				if (StrUtil.isBlank(password)) {
					sysUserTeacherImportVo.setPassword(passwordEncoder.encode("12345678"));
				} else {
					sysUserTeacherImportVo.setPassword(passwordEncoder.encode(sysUserTeacherImportVo.getPassword()));
				}
				
				
				SysUser sysUser = new SysUser();
				BeanUtil.copyProperties(sysUserTeacherImportVo, sysUser);
				
				LambdaQueryWrapper<SysDept> sysDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
				sysDeptLambdaQueryWrapper.eq(SysDept::getName, sysUserTeacherImportVo.getDeptName());
				sysDeptLambdaQueryWrapper.eq(SysDept::getTenantId, SysUserUtils.getSysUser().getTenantId());
				List<SysDept> list = this.sysDeptService.list(sysDeptLambdaQueryWrapper);
				if (list == null || list.size() == 0) {
					continue;
				} else {
					sysUser.setDeptId(list.get(0).getId());
					sysUser.setDeptName(list.get(0).getName());
				}
				SysRole role = sysRoleService.getRoleByName("教员");
				sysUser.setTenantId(SysUserUtils.getSysUser().getTenantId());
				if (dbUserNameInfo == null) {
					sysUserService.insertUserAndRole(sysUser, role.getId());
				} else {
					sysUserService.update(dbUserNameInfo.getId(), sysUser);
					sysUserService.insertUserRoleRalation(dbUserNameInfo.getId(), role.getId());
				}
			} catch (Exception e) {
				LOGGER.error("导入用户[" + sysUserTeacherImportVo.getUsername() + "]失败:", e);
			}
			
			
		}
		LOGGER.info("存储数据库成功！");
	}
}
